#include "bsp.h"

#include "bsp_spi.h"
#include "drv_wifi.h"

data_fifo_t wifi_fifo;
volatile uint8_t initiative_send_flag = 0; // it means master has data to send to slave
uint32_t plan_send_len = 0;                // master plan to send data len
volatile uint8_t gpio_trigger_evt;

// #1. 发送写数据请求.
void slm_at_write_request(uint16_t plan_send_len)
{
    uint8_t w_request[6];

    w_request[0] = CMD_WRITE_REQUEST;
    w_request[1] = 0x00;
    w_request[2] = 0xEF;
    w_request[3] = 1;
    *(uint16_t *)&w_request[4] = plan_send_len;

    if (app_spi_write_data(w_request, 6) != 0)
    {
        printf("[e] Write Request\n");
    }
}

// #3. 发送读取状态请求.
int slm_at_read_slave_trans_info(uint8_t **rx_buf)
{
    uint8_t w_request[6];

    w_request[0] = CMD_READ_STATUS_REQUEST;
    w_request[1] = 0x00;

    if (app_spi_write_read_data(w_request, 6, rx_buf, 6) != 0)
    {
        printf("SPI WR Failed!\n");
        return -1;
    }
    return 0;
}

// #4. 发送有效数据,并发送结束.
void slm_at_send_data(uint8_t *data, uint16_t len)
{
    // #4. 发送数据
    data[0] = CMD_WIRTE_DATA;
    data[1] = 0x00;

    if (app_spi_write_data(data, len + 2) != 0)
    {
        printf("[e] Send Data\n");
    }
}

// #5. 发送读取数据请求.
void slm_at_read_data(uint8_t **data, uint16_t len)
{
    uint8_t w_data[2];

    // #4. 发送数据
    w_data[0] = CMD_READ_DATA;
    w_data[1] = 0x00;

    if (app_spi_write_read_data(w_data, 2, data, len + 2) != 0)
    {
        printf("[e] Read Data");
    }
}

// #0. 请求一次数据传输.
void notify_slave_to_recv(void)
{
    if (initiative_send_flag == 0)
    {
        uint32_t tmp_send_len = data_fifo_first_size_read(&wifi_fifo);
        if (tmp_send_len > 0)
        {
            plan_send_len = tmp_send_len > SPI_TRANS_DATA_BUFF_SIZE ? SPI_TRANS_DATA_BUFF_SIZE : tmp_send_len;

            slm_at_write_request(plan_send_len);
            initiative_send_flag = 1;
						bsp_DelayUS(100);
					
        }
    }
    else
    {
        printf("Busy\r\n");
    }
}

int drv_wifi_spi_buff_write(uint8_t *data, uint16_t length)
{
    return data_fifo_write(&wifi_fifo, data, length);
}

int drv_wifi_process(void)
{
    uint8_t Buff[1408];
    uint8_t *spi_rx_buff;
    read_status_t *read_status;

    // 处理5302的引脚状态函数.
    if (gpio_trigger_evt)
    {
        gpio_trigger_evt = false;
				
        if (slm_at_read_slave_trans_info(&spi_rx_buff) == 0)
        {
            read_status = (read_status_t *)spi_rx_buff;

            if (read_status->status == CMD_STATUS_WRITE)
            {
                if (plan_send_len == 0)
                {
                    printf("master want send data but length is 0\n");
                    return -1;
                }

                uint16_t txLength;
                uint8_t ret;

                // initiative_send_flag = 0;
                ret = data_fifo_read(&wifi_fifo, &Buff[2], &txLength);
                if ((ret == 0) || (plan_send_len != txLength))
                {
                    printf("Read len expect %d, but actual read%d\n", plan_send_len, txLength);
										initiative_send_flag = 0;
                    return -1;
                }

                bsp_DelayUS(100);

                slm_at_send_data(Buff, plan_send_len);
                bsp_DelayUS(100);

                if (GPIO_ReadInputDataBit(DRV_HANDSHAKE_PORT, DRV_HANDSHAKE_PIN) == 1)
                {
                    gpio_trigger_evt = 1;
										initiative_send_flag = 0;
                }
                else
                {
                    uint16_t tmp_send_len = data_fifo_first_size_read(&wifi_fifo);
                    if (tmp_send_len != 0)
                    {
                        plan_send_len = tmp_send_len > SPI_TRANS_DATA_BUFF_SIZE ? SPI_TRANS_DATA_BUFF_SIZE : tmp_send_len;

                        slm_at_write_request(plan_send_len);
                        initiative_send_flag = 1;
												bsp_DelayUS(100);
                    }
                    else
                    {
                        initiative_send_flag = 0;
                    }
                }
            }
            else if (read_status->status == CMD_STATUS_READ)
            {
                uint16_t transmit_len = read_status->len;

                if (transmit_len > SPI_TRANS_DATA_BUFF_SIZE || transmit_len == 0)
                {
                    printf("SPI read len error, %x\n", transmit_len);
                    return -1;
                }

                bsp_DelayUS(100);

                slm_at_read_data(&spi_rx_buff, transmit_len);

                if ((spi_rx_buff[2] != 0xA5) && (spi_rx_buff[2] != 0x5A))
                {
										comSendBuf(COM1, &spi_rx_buff[2], transmit_len);
                }
								
								bsp_DelayUS(100);

                if (GPIO_ReadInputDataBit(DRV_HANDSHAKE_PORT, DRV_HANDSHAKE_PIN) == 1)
                {
                    gpio_trigger_evt = 1;
                }
            }
            else
            {
                if (initiative_send_flag == true)
                {
                    printf("SPI write len error\r\n");
                    initiative_send_flag = false;
                }
            }
        }
        else
        {
            if (initiative_send_flag == true)
            {
                printf("SPI write len error\r\n");
                initiative_send_flag = false;
            }
        }
    }

    return 0;
}

void EXTI9_5_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line6) != RESET)
    {
        uint8_t level_value = GPIO_ReadInputDataBit(DRV_HANDSHAKE_PORT, DRV_HANDSHAKE_PIN);
        if (level_value == 1)
        {
            gpio_trigger_evt = true;
        }
        EXTI_ClearITPendingBit(EXTI_Line6); /* 清除中断标志位 */
    }
}

void EXTI4_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line4) != RESET)
    {
        uint8_t level_value = GPIO_ReadInputDataBit(DRV_HANDSHAKE_PORT, DRV_HANDSHAKE_PIN);
        if (level_value == 1)
        {
            gpio_trigger_evt = true;
        }
        EXTI_ClearITPendingBit(EXTI_Line4); /* 清除中断标志位 */
    }
}

void handshake_gpio_init(void)
{
    EXTI_InitTypeDef EXTI_InitStructure = {0};
		GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;		/* 设为输入口 */
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		/* 设为推挽模式 */
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;	/* 无需上下拉电阻 */
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	/* IO口最大速度 */

		GPIO_InitStructure.GPIO_Pin = DRV_HANDSHAKE_PIN;
		GPIO_Init(DRV_HANDSHAKE_PORT, &GPIO_InitStructure);

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource4);

    /* 配置 EXTI LineXXX */
    EXTI_InitStructure.EXTI_Line = EXTI_Line4;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
		
		HAL_NVIC_SetPriority(EXTI4_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(EXTI4_IRQn);
	
    uint32_t level_value = GPIO_ReadInputDataBit(DRV_HANDSHAKE_PORT, DRV_HANDSHAKE_PIN);
    if (level_value == 1)
    {
        gpio_trigger_evt = true;
    }
}

int drv_wifi_init(void)
{
		bsp_InitSpi();  
		handshake_gpio_init();	
    return 0;
}
